function objectToString(o: any) {
    return Object.prototype.toString.call(o);
}

class Is {
    static date(d: any) {
        return objectToString(d) === '[object Date]';
    }
    static regExp(re: any) {
        return objectToString(re) === '[object RegExp]';
    }
    static undefined(arg: any) {
        return arg === void 0;
    }
    static symbol(arg: any) {
        return typeof arg === 'symbol';
    }
    static string(arg: any) {
        return typeof arg === 'string';
    }
    number(arg: any) {
        return typeof arg === 'number';
    }
    notANumber(arg: any) {
        let is = false;
        if (this.number(arg) && isNaN(arg)) {
            is = true;
        }
        return is;
    }
    numeric(mixedVar: any) {
        // eslint-disable-line camelcase
        //  discuss at: https://locutus.io/php/is_numeric/
        // original by: Kevin van Zonneveld (https://kvz.io)
        // improved by: David
        // improved by: taith
        // bugfixed by: Tim de Koning
        // bugfixed by: WebDevHobo (https://webdevhobo.blogspot.com/)
        // bugfixed by: Brett Zamir (https://brett-zamir.me)
        // bugfixed by: Denis Chenu (https://shnoulle.net)
        //   example 1: is_numeric(186.31)
        //   returns 1: true
        //   example 2: is_numeric('Kevin van Zonneveld')
        //   returns 2: false
        //   example 3: is_numeric(' +186.31e2')
        //   returns 3: true
        //   example 4: is_numeric('')
        //   returns 4: false
        //   example 5: is_numeric([])
        //   returns 5: false
        //   example 6: is_numeric('1 ')
        //   returns 6: false
        const whitespace = [
            ' ',
            '\n',
            '\r',
            '\t',
            '\f',
            '\x0b',
            '\xa0',
            '\u2000',
            '\u2001',
            '\u2002',
            '\u2003',
            '\u2004',
            '\u2005',
            '\u2006',
            '\u2007',
            '\u2008',
            '\u2009',
            '\u200a',
            '\u200b',
            '\u2028',
            '\u2029',
            '\u3000',
        ].join('');

        // @todo: Break this up using many single conditions with early returns
        return (typeof mixedVar === 'number' ||
            (typeof mixedVar === 'string' &&
                whitespace.indexOf(mixedVar.slice(-1)) === -1)) &&
            mixedVar !== '' &&
            !this.notANumber(mixedVar);
    }
    nullOrUndefined(arg: any) {
        return arg == null;
    }
    null(arg: any) {
        return arg === null;
    }
    boolean(arg: any) {
        return typeof arg === 'boolean';
    }
    array(arg: any) {
        if (Array.isArray) {
            return Array.isArray(arg);
        }
        return objectToString(arg) === '[object Array]';
    }
    object(arg: any) {
        return typeof arg === 'object' && arg !== null && Array.isArray(arg) === false;
    }
    error(e: any) {
        return (objectToString(e) === '[object Error]' || e instanceof Error);
    }
    function(arg: any) {
        return typeof arg === 'function';
    }
    primitive(arg: any) {
        return arg === null ||
            typeof arg === 'boolean' ||
            typeof arg === 'number' ||
            typeof arg === 'string' ||
            typeof arg === 'symbol' ||
            typeof arg === 'undefined';
    }
};